import java.util.Random;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author christianhansen
 */
public class CompSort extends JFrame {

    /**
     * Creates new form CompSort
     */
    public CompSort() {
        initComponents();            //from netbeans gui
        initComponentsManually();    //added by hand
        m_timer = new StopWatch();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        startButton = new javax.swing.JButton();
        integerRadioButton = new javax.swing.JRadioButton();
        characterRadioButton = new javax.swing.JRadioButton();
        itemsLabel = new javax.swing.JLabel();
        itemsComboBox = new javax.swing.JComboBox();
        insertionSortPanel = new javax.swing.JPanel();
        iSortTimeLabel = new javax.swing.JLabel();
        iTimeLabel = new javax.swing.JLabel();
        iListLabel = new javax.swing.JLabel();
        iAverageSortTimeLabel = new javax.swing.JLabel();
        iAvTimeLabel = new javax.swing.JLabel();
        iStatusLabel = new javax.swing.JLabel();
        resetButton = new javax.swing.JButton();
        bubbleSortPanel = new javax.swing.JPanel();
        bSortTimeLabel = new javax.swing.JLabel();
        bTimeLabel = new javax.swing.JLabel();
        bListLabel = new javax.swing.JLabel();
        bAverageSortTimeLabel = new javax.swing.JLabel();
        bAvTimeLabel = new javax.swing.JLabel();
        bStatusLabel = new javax.swing.JLabel();
        finalTimesLabel = new javax.swing.JLabel();
        quickSortPanel = new javax.swing.JPanel();
        qSortTimeLabel = new javax.swing.JLabel();
        qTimeLabel = new javax.swing.JLabel();
        qListLabel = new javax.swing.JLabel();
        qAverageSortTimeLabel = new javax.swing.JLabel();
        qAvTimeLabel = new javax.swing.JLabel();
        qStatusLabel = new javax.swing.JLabel();
        nIntComboBox = new javax.swing.JComboBox();
        nIntLabel = new javax.swing.JLabel();
        selectionSortPanel = new javax.swing.JPanel();
        sSortTimeLabel = new javax.swing.JLabel();
        sTimeLabel = new javax.swing.JLabel();
        sListLabel = new javax.swing.JLabel();
        sAverageSortTimeLabel = new javax.swing.JLabel();
        sAvTimeLabel = new javax.swing.JLabel();
        sStatusLabel = new javax.swing.JLabel();
        mergeSortPanel = new javax.swing.JPanel();
        mSortTimeLabel = new javax.swing.JLabel();
        mTimeLabel = new javax.swing.JLabel();
        mListLabel = new javax.swing.JLabel();
        mAverageSortTimeLabel = new javax.swing.JLabel();
        mAvTimeLabel = new javax.swing.JLabel();
        mStatusLabel = new javax.swing.JLabel();
        heapSortPanel = new javax.swing.JPanel();
        hSortTimeLabel = new javax.swing.JLabel();
        hTimeLabel = new javax.swing.JLabel();
        hListLabel = new javax.swing.JLabel();
        hAverageSortTimeLabel = new javax.swing.JLabel();
        hAvTimeLabel = new javax.swing.JLabel();
        hStatusLabel = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        startButton.setBackground(new java.awt.Color(0, 204, 51));
        startButton.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
        startButton.setText("Shuffle");
        startButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startButtonActionPerformed(evt);
            }
        });

        buttonGroup1.add(integerRadioButton);
        integerRadioButton.setSelected(true);
        integerRadioButton.setText("Fill with Integers");
        integerRadioButton.setAlignmentY(0.0F);
        integerRadioButton.setBorder(null);
        integerRadioButton.setFocusable(false);
        integerRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                integerRadioButtonActionPerformed(evt);
            }
        });

        buttonGroup1.add(characterRadioButton);
        characterRadioButton.setText("Fill with Characters");
        characterRadioButton.setAlignmentY(0.0F);
        characterRadioButton.setBorder(null);
        characterRadioButton.setFocusable(false);
        characterRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                characterRadioButtonActionPerformed(evt);
            }
        });

        itemsLabel.setText("Number Items:");

        itemsComboBox.setEditable(true);
        itemsComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        insertionSortPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Insertion Sort"));
        insertionSortPanel.setAutoscrolls(true);
        insertionSortPanel.setMaximumSize(new java.awt.Dimension(695, 94));
        insertionSortPanel.setMinimumSize(new java.awt.Dimension(695, 94));
        insertionSortPanel.setPreferredSize(new java.awt.Dimension(695, 94));
        insertionSortPanel.setRequestFocusEnabled(false);

        iSortTimeLabel.setText("0");

        iTimeLabel.setText("Sort Time:");

        iAverageSortTimeLabel.setText("0");

        iAvTimeLabel.setText("Average Sort Time:");

        iStatusLabel.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
        iStatusLabel.setText("EMPTY");

        org.jdesktop.layout.GroupLayout insertionSortPanelLayout = new org.jdesktop.layout.GroupLayout(insertionSortPanel);
        insertionSortPanel.setLayout(insertionSortPanelLayout);
        insertionSortPanelLayout.setHorizontalGroup(
            insertionSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(insertionSortPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(insertionSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(insertionSortPanelLayout.createSequentialGroup()
                        .add(iListLabel)
                        .addContainerGap())
                    .add(insertionSortPanelLayout.createSequentialGroup()
                        .add(iTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(iSortTimeLabel)
                        .add(158, 158, 158)
                        .add(iAvTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(iAverageSortTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(iStatusLabel)
                        .add(198, 198, 198))))
        );
        insertionSortPanelLayout.setVerticalGroup(
            insertionSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(insertionSortPanelLayout.createSequentialGroup()
                .add(insertionSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(iTimeLabel)
                    .add(iSortTimeLabel)
                    .add(iAvTimeLabel)
                    .add(iAverageSortTimeLabel)
                    .add(iStatusLabel))
                .add(18, 18, 18)
                .add(iListLabel)
                .addContainerGap())
        );

        resetButton.setBackground(new java.awt.Color(102, 0, 255));
        resetButton.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
        resetButton.setText("Reset");
        resetButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                resetButtonActionPerformed(evt);
            }
        });

        bubbleSortPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Bubble Sort"));
        bubbleSortPanel.setAutoscrolls(true);
        bubbleSortPanel.setMaximumSize(new java.awt.Dimension(695, 94));
        bubbleSortPanel.setMinimumSize(new java.awt.Dimension(695, 94));
        bubbleSortPanel.setPreferredSize(new java.awt.Dimension(695, 94));
        bubbleSortPanel.setRequestFocusEnabled(false);

        bSortTimeLabel.setText("0");

        bTimeLabel.setText("Sort Time:");

        bAverageSortTimeLabel.setText("0");

        bAvTimeLabel.setText("Average Sort Time:");

        bStatusLabel.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
        bStatusLabel.setText("EMPTY");

        org.jdesktop.layout.GroupLayout bubbleSortPanelLayout = new org.jdesktop.layout.GroupLayout(bubbleSortPanel);
        bubbleSortPanel.setLayout(bubbleSortPanelLayout);
        bubbleSortPanelLayout.setHorizontalGroup(
            bubbleSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(bubbleSortPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(bubbleSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(bubbleSortPanelLayout.createSequentialGroup()
                        .add(bListLabel)
                        .addContainerGap())
                    .add(bubbleSortPanelLayout.createSequentialGroup()
                        .add(bTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(bSortTimeLabel)
                        .add(158, 158, 158)
                        .add(bAvTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(bAverageSortTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(bStatusLabel)
                        .add(203, 203, 203))))
        );
        bubbleSortPanelLayout.setVerticalGroup(
            bubbleSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(bubbleSortPanelLayout.createSequentialGroup()
                .add(bubbleSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(bTimeLabel)
                    .add(bSortTimeLabel)
                    .add(bAvTimeLabel)
                    .add(bAverageSortTimeLabel)
                    .add(bStatusLabel))
                .add(18, 18, 18)
                .add(bListLabel)
                .addContainerGap())
        );

        finalTimesLabel.setText("         ");

        quickSortPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Quick Sort (recursive)"));
        quickSortPanel.setAutoscrolls(true);
        quickSortPanel.setMaximumSize(new java.awt.Dimension(695, 94));
        quickSortPanel.setMinimumSize(new java.awt.Dimension(695, 94));
        quickSortPanel.setPreferredSize(new java.awt.Dimension(695, 94));
        quickSortPanel.setRequestFocusEnabled(false);

        qSortTimeLabel.setText("0");

        qTimeLabel.setText("Sort Time:");

        qAverageSortTimeLabel.setText("0");

        qAvTimeLabel.setText("Average Sort Time:");

        qStatusLabel.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
        qStatusLabel.setText("EMPTY");

        org.jdesktop.layout.GroupLayout quickSortPanelLayout = new org.jdesktop.layout.GroupLayout(quickSortPanel);
        quickSortPanel.setLayout(quickSortPanelLayout);
        quickSortPanelLayout.setHorizontalGroup(
            quickSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(quickSortPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(quickSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(quickSortPanelLayout.createSequentialGroup()
                        .add(qListLabel)
                        .addContainerGap())
                    .add(quickSortPanelLayout.createSequentialGroup()
                        .add(qTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(qSortTimeLabel)
                        .add(158, 158, 158)
                        .add(qAvTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(qAverageSortTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(qStatusLabel)
                        .add(207, 207, 207))))
        );
        quickSortPanelLayout.setVerticalGroup(
            quickSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(quickSortPanelLayout.createSequentialGroup()
                .add(quickSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(qTimeLabel)
                    .add(qSortTimeLabel)
                    .add(qAvTimeLabel)
                    .add(qAverageSortTimeLabel)
                    .add(qStatusLabel))
                .add(18, 18, 18)
                .add(qListLabel)
                .addContainerGap())
        );

        nIntComboBox.setEditable(true);
        nIntComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        nIntComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nIntComboBoxActionPerformed(evt);
            }
        });

        nIntLabel.setText("Number Possible Integers:");

        selectionSortPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Selection Sort"));
        selectionSortPanel.setAutoscrolls(true);
        selectionSortPanel.setMaximumSize(new java.awt.Dimension(695, 94));
        selectionSortPanel.setMinimumSize(new java.awt.Dimension(695, 94));
        selectionSortPanel.setPreferredSize(new java.awt.Dimension(1040, 94));
        selectionSortPanel.setRequestFocusEnabled(false);

        sSortTimeLabel.setText("0");

        sTimeLabel.setText("Sort Time:");

        sAverageSortTimeLabel.setText("0");

        sAvTimeLabel.setText("Average Sort Time:");

        sStatusLabel.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
        sStatusLabel.setText("EMPTY");

        org.jdesktop.layout.GroupLayout selectionSortPanelLayout = new org.jdesktop.layout.GroupLayout(selectionSortPanel);
        selectionSortPanel.setLayout(selectionSortPanelLayout);
        selectionSortPanelLayout.setHorizontalGroup(
            selectionSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(selectionSortPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(selectionSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(selectionSortPanelLayout.createSequentialGroup()
                        .add(sListLabel)
                        .addContainerGap())
                    .add(selectionSortPanelLayout.createSequentialGroup()
                        .add(sTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(sSortTimeLabel)
                        .add(158, 158, 158)
                        .add(sAvTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(sAverageSortTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 401, Short.MAX_VALUE)
                        .add(sStatusLabel)
                        .add(207, 207, 207))))
        );
        selectionSortPanelLayout.setVerticalGroup(
            selectionSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(selectionSortPanelLayout.createSequentialGroup()
                .add(selectionSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(sTimeLabel)
                    .add(sSortTimeLabel)
                    .add(sAvTimeLabel)
                    .add(sAverageSortTimeLabel)
                    .add(sStatusLabel))
                .add(18, 18, 18)
                .add(sListLabel)
                .addContainerGap())
        );

        mergeSortPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Merge Sort (not recursive)"));
        mergeSortPanel.setAutoscrolls(true);
        mergeSortPanel.setMaximumSize(new java.awt.Dimension(695, 94));
        mergeSortPanel.setMinimumSize(new java.awt.Dimension(695, 94));
        mergeSortPanel.setPreferredSize(new java.awt.Dimension(1040, 94));
        mergeSortPanel.setRequestFocusEnabled(false);

        mSortTimeLabel.setText("0");

        mTimeLabel.setText("Sort Time:");

        mAverageSortTimeLabel.setText("0");

        mAvTimeLabel.setText("Average Sort Time:");

        mStatusLabel.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
        mStatusLabel.setText("EMPTY");

        org.jdesktop.layout.GroupLayout mergeSortPanelLayout = new org.jdesktop.layout.GroupLayout(mergeSortPanel);
        mergeSortPanel.setLayout(mergeSortPanelLayout);
        mergeSortPanelLayout.setHorizontalGroup(
            mergeSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(mergeSortPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(mergeSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(mergeSortPanelLayout.createSequentialGroup()
                        .add(mListLabel)
                        .addContainerGap())
                    .add(mergeSortPanelLayout.createSequentialGroup()
                        .add(mTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(mSortTimeLabel)
                        .add(158, 158, 158)
                        .add(mAvTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(mAverageSortTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 401, Short.MAX_VALUE)
                        .add(mStatusLabel)
                        .add(207, 207, 207))))
        );
        mergeSortPanelLayout.setVerticalGroup(
            mergeSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(mergeSortPanelLayout.createSequentialGroup()
                .add(mergeSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(mTimeLabel)
                    .add(mSortTimeLabel)
                    .add(mAvTimeLabel)
                    .add(mAverageSortTimeLabel)
                    .add(mStatusLabel))
                .add(18, 18, 18)
                .add(mListLabel)
                .addContainerGap())
        );

        heapSortPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Heap Sort"));
        heapSortPanel.setAutoscrolls(true);
        heapSortPanel.setMaximumSize(new java.awt.Dimension(695, 94));
        heapSortPanel.setMinimumSize(new java.awt.Dimension(695, 94));
        heapSortPanel.setPreferredSize(new java.awt.Dimension(645, 94));
        heapSortPanel.setRequestFocusEnabled(false);

        hSortTimeLabel.setText("0");

        hTimeLabel.setText("Sort Time:");

        hAverageSortTimeLabel.setText("0");

        hAvTimeLabel.setText("Average Sort Time:");

        hStatusLabel.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
        hStatusLabel.setText("EMPTY");

        org.jdesktop.layout.GroupLayout heapSortPanelLayout = new org.jdesktop.layout.GroupLayout(heapSortPanel);
        heapSortPanel.setLayout(heapSortPanelLayout);
        heapSortPanelLayout.setHorizontalGroup(
            heapSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(heapSortPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(heapSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(heapSortPanelLayout.createSequentialGroup()
                        .add(hListLabel)
                        .addContainerGap())
                    .add(heapSortPanelLayout.createSequentialGroup()
                        .add(hTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(hSortTimeLabel)
                        .add(158, 158, 158)
                        .add(hAvTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(hAverageSortTimeLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(hStatusLabel)
                        .add(207, 207, 207))))
        );
        heapSortPanelLayout.setVerticalGroup(
            heapSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(heapSortPanelLayout.createSequentialGroup()
                .add(heapSortPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(hTimeLabel)
                    .add(hSortTimeLabel)
                    .add(hAvTimeLabel)
                    .add(hAverageSortTimeLabel)
                    .add(hStatusLabel))
                .add(18, 18, 18)
                .add(hListLabel)
                .addContainerGap())
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(33, 33, 33)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                        .add(startButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 77, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(30, 30, 30)
                        .add(resetButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 77, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(45, 45, 45)
                        .add(itemsLabel)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(itemsComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(40, 40, 40)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(characterRadioButton)
                            .add(layout.createSequentialGroup()
                                .add(integerRadioButton)
                                .add(90, 90, 90)
                                .add(nIntLabel)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(nIntComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                        .addContainerGap())
                    .add(layout.createSequentialGroup()
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                                .add(bubbleSortPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1040, Short.MAX_VALUE)
                                .add(quickSortPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1040, Short.MAX_VALUE)
                                .add(insertionSortPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1040, Short.MAX_VALUE)
                                .add(selectionSortPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .add(heapSortPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1040, Short.MAX_VALUE))
                            .add(mergeSortPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(finalTimesLabel))
                        .add(0, 55, Short.MAX_VALUE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                        .add(startButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 37, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(itemsLabel)
                        .add(itemsComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(resetButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 37, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .add(layout.createSequentialGroup()
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(integerRadioButton)
                            .add(nIntLabel)
                            .add(nIntComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(characterRadioButton)))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(bubbleSortPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(selectionSortPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(insertionSortPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(mergeSortPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(quickSortPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(heapSortPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 49, Short.MAX_VALUE)
                .add(finalTimesLabel)
                .addContainerGap())
        );

        quickSortPanel.getAccessibleContext().setAccessibleName("Quick Sort");

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void initComponentsManually() {
        m_rand = new Random();
        m_Nalgos = 6;
        m_algos = new SortAlgorithm[m_Nalgos];
        m_algos[0] = new InsertionSort(iListLabel, iSortTimeLabel, iAverageSortTimeLabel, iStatusLabel);
        m_algos[1] = new BubbleSort(bListLabel, bSortTimeLabel, bAverageSortTimeLabel, bStatusLabel);
        m_algos[2] = new QuickSort(qListLabel, qSortTimeLabel, qAverageSortTimeLabel, qStatusLabel);
        m_algos[3] = new SelectionSort(sListLabel, sSortTimeLabel, sAverageSortTimeLabel, sStatusLabel);
        m_algos[4] = new MergeSort(mListLabel, mSortTimeLabel, mAverageSortTimeLabel, mStatusLabel);
        m_algos[5] = new HeapSort(hListLabel, hSortTimeLabel, hAverageSortTimeLabel, hStatusLabel);
        //Define how the ComboBox for number items should look like
        String [] itemValues = new String[9999];
        int j = 0;
        for(int i = 10; i < 100000 ; i += 10) itemValues[j++] = Integer.toString(i);
        itemsComboBox.setModel(new javax.swing.DefaultComboBoxModel(itemValues));
        itemsComboBox.setSelectedIndex(3);
        //Define how the ComboBox for number possible Integers should look like
        String [] nIntValues = new String[99];
        j = 0;
        for(int i = 10; i < 1000 ; i += 10) nIntValues[j++] = Integer.toString(i);
        nIntComboBox.setModel(new javax.swing.DefaultComboBoxModel(nIntValues));
        nIntComboBox.setSelectedIndex(9);
        //Start and Reset buttons
        startButton.setActionCommand("shuffle");
        startButton.setToolTipText("Shuffle randomly the items.");
        resetButton.setToolTipText("Clear all items and results and enable the options.");
        //For default (int 100) 40 is good max number items to print
        setAllMaxItToPrint(41);
    }
    
    private void printAllLists()  { for (int i = 0; i < m_Nalgos; i++) m_algos[i].printList();   }
    private void resetAllAlgos()  { for (int i = 0; i < m_Nalgos; i++) m_algos[i].reset();       }
    private void clearAllAlgos()  { for (int i = 0; i < m_Nalgos; i++) m_algos[i].clearList();   }
    private void setAllShuffled() { for (int i = 0; i < m_Nalgos; i++) m_algos[i].setShuffled(); }
    private void setAllSorting()  { for (int i = 0; i < m_Nalgos; i++) m_algos[i].setSorting();  }
    private void setAllChecking() { for (int i = 0; i < m_Nalgos; i++) m_algos[i].setChecking(); }
    private void fillAllAlgos(Comparable item) { for (int i = 0; i < m_Nalgos; i++) m_algos[i].fill(item); }
    private void setAllMaxItToPrint(int maxIt) { for (int i = 0; i < m_Nalgos; i++) m_algos[i].setMaxNItemsToPrint(maxIt); }
 
    private class ShuffleThread extends SwingWorker<Void, Void> {
        @Override
        protected Void doInBackground() {
            clearAllAlgos();
            if (m_useCharacters) {
                for (int i = 0; i < m_nItems; i++) fillAllAlgos( (Comparable)( (char)(m_rand.nextInt(26) + 'A') ) );
            } else {
                for (int i = 0; i < m_nItems; i++) fillAllAlgos( (Comparable)( (int)(m_rand.nextInt(m_nInt)) ) );
            }
            return null;
        }
        @Override
        protected void done() { 
            setAllShuffled();
            printAllLists();  
            startButton.setEnabled(true);
            resetButton.setEnabled(true);
            //Reset the start button to sort mode
            startButton.setText("Sort"); 
            startButton.setActionCommand("sort");
            startButton.setToolTipText("Start sorting the items with all sorting algorithms.");
        }
    }
    
    private void enableOptions(boolean enable) {
        characterRadioButton.setEnabled(enable);
        integerRadioButton.setEnabled(enable);
        itemsLabel.setEnabled(enable);
        itemsComboBox.setEnabled(enable);
        if (integerRadioButton.isSelected()) {
            nIntComboBox.setEnabled(enable);
            nIntLabel.setEnabled(enable);
        } 
    }
    
    private void readOptions() {
        m_nItems = Integer.parseInt((String)itemsComboBox.getSelectedItem());
        m_nInt = Integer.parseInt((String)nIntComboBox.getSelectedItem());
        m_useCharacters = characterRadioButton.isSelected();
    }
    
     
    private class SortThread extends SwingWorker<Pair<Long, Long>, Void> {
        Long iTime, bTime, qTime, sTime, mTime, hTime;
        @Override
        protected Pair<Long, Long> doInBackground() {
            try {
                setAllSorting();
                m_timer.reset();
                m_timer.start(); 
                (i_algoSortThread = new AlgoSortThread(m_algos[0])).execute();
                (b_algoSortThread = new AlgoSortThread(m_algos[1])).execute();
                (q_algoSortThread = new AlgoSortThread(m_algos[2])).execute();
                (s_algoSortThread = new AlgoSortThread(m_algos[3])).execute();
                (m_algoSortThread = new AlgoSortThread(m_algos[4])).execute();
                (h_algoSortThread = new AlgoSortThread(m_algos[5])).execute();
                iTime = i_algoSortThread.get();  //BLOCKS until Insertion Sort is done
                bTime = b_algoSortThread.get();  //BLOCKS until Bubble Sort is done
                qTime = q_algoSortThread.get();  //BLOCKS until Quick Sort is done
                sTime = s_algoSortThread.get();  //BLOCKS until Selection Sort is done
                mTime = m_algoSortThread.get();  //BLOCKS until Merge Sort is done
                hTime = h_algoSortThread.get();  //BLOCKS until Heap Sort is done
                m_timer.stop();
                setAllChecking();
                (i_algoCheckThread = new AlgoCheckThread(m_algos[0])).execute();
                (b_algoCheckThread = new AlgoCheckThread(m_algos[1])).execute();
                (q_algoCheckThread = new AlgoCheckThread(m_algos[2])).execute();
                (s_algoCheckThread = new AlgoCheckThread(m_algos[3])).execute();
                (m_algoCheckThread = new AlgoCheckThread(m_algos[4])).execute();
                (h_algoCheckThread = new AlgoCheckThread(m_algos[5])).execute();
                i_algoCheckThread.get();  //BLOCKS until Insertion Sort is done
                b_algoCheckThread.get();  //BLOCKS until Bubble Sort is done
                q_algoCheckThread.get();  //BLOCKS until Quick Sort is done
                s_algoCheckThread.get();  //BLOCKS until Selection Sort is done
                m_algoCheckThread.get();  //BLOCKS until Merge Sort is done
                h_algoCheckThread.get();  //BLOCKS until Heap Sort is done
            } catch (Exception ignore) {  System.out.println("An Exception occured in an algo-sort thread or in an algo-check thread."); }
            return new Pair<Long, Long>(m_timer.getElapsedTime(), iTime+bTime+qTime);
        }
        @Override
        protected void done() {
            try {
                Pair<Long, Long> times = get();
                if (times.first < times.second) {   //Otherwice we used too few items and no need to see this
                    finalTimesLabel.setText("All sorting algorithms finish after "+times.first+" ms, i.e. faster than the total sorting time: "+times.second+" ms  (thanks to threads).");
                }
                startButton.setEnabled(true);
                resetButton.setEnabled(true);
                //Reset the start button to shuffle mode
                startButton.setText("Shuffle");
                startButton.setActionCommand("shuffle");
                startButton.setToolTipText("Shuffle randomly the items.");
            } catch (Exception ignore) { System.out.println("An algo-sort- or algo-check-thread Exception caught in done() of SortThread."); }        
        }
    }
    private class AlgoSortThread extends SwingWorker<Long, Void> {
        SortAlgorithm m_algo;
        AlgoSortThread(SortAlgorithm algo) { m_algo = algo; }
        @Override
        protected Long doInBackground() { return m_algo.sortBenchmarkAndShow(); }
        @Override
        protected void done() { m_algo.setDone(); }
    }
    private class AlgoCheckThread extends SwingWorker<Boolean, Void> {
        SortAlgorithm m_algo;
        AlgoCheckThread(SortAlgorithm algo) {m_algo = algo;}
        @Override
        protected Boolean doInBackground() { return Boolean.valueOf(m_algo.isSorted()); }
        @Override
        protected void done() { 
            try {
                if (get()) { 
                    m_algo.setSorted();
                } else {
                    m_algo.setFailed();
                }
            } catch(Exception ignore) { System.out.println("A check-thread Exception caught in done() of AlgoCheckThread."); }
        }
    }
    
    
    private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed
        if (evt.getActionCommand().equals("sort")) {
            startButton.setEnabled(false);
            resetButton.setEnabled(false);
            //SORT
            (sortThread = new SortThread()).execute();
        } else {
            if (itemsLabel.isEnabled()) {
                readOptions();
                enableOptions(false);
            }
            startButton.setEnabled(false);
            resetButton.setEnabled(false);
            //SHUFFLE
            (shuffleThread = new ShuffleThread()).execute();
            
            sortThread = null;
            shuffleThread = null;
        }
    }//GEN-LAST:event_startButtonActionPerformed

    private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetButtonActionPerformed
        resetAllAlgos();
        enableOptions(true);
        startButton.setText("Shuffle");
        startButton.setActionCommand("shuffle");
        finalTimesLabel.setText("  ");
    }//GEN-LAST:event_resetButtonActionPerformed

    private void integerRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_integerRadioButtonActionPerformed
        if (integerRadioButton.isSelected()) {
            nIntComboBox.setEnabled(true);
            nIntLabel.setEnabled(true);
            setAllMaxItToPrint(31);
        } 
    }//GEN-LAST:event_integerRadioButtonActionPerformed

    private void characterRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_characterRadioButtonActionPerformed
         if (characterRadioButton.isSelected()) {
            nIntComboBox.setEnabled(false);
            nIntLabel.setEnabled(false);
            setAllMaxItToPrint(61);
        } 
    }//GEN-LAST:event_characterRadioButtonActionPerformed

    private void nIntComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nIntComboBoxActionPerformed
        m_nInt = Integer.parseInt((String)nIntComboBox.getSelectedItem());
        if (m_nInt < 11) {
            setAllMaxItToPrint(61);
        } else if (m_nInt < 199) {
            setAllMaxItToPrint(51);
        } else if (m_nInt < 399) {
            setAllMaxItToPrint(41);
        } else {
            setAllMaxItToPrint(31);
        }
    }//GEN-LAST:event_nIntComboBoxActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(CompSort.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(CompSort.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(CompSort.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(CompSort.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {
         
            public void run() {
                new CompSort().setVisible(true);
            }
        });
    }
    private SortAlgorithm[] m_algos;
    private int m_Nalgos;
    private int m_nItems, m_nInt;
    private Random m_rand;
    private boolean m_useCharacters;
    private SortThread sortThread;
    private AlgoSortThread i_algoSortThread, b_algoSortThread, q_algoSortThread, s_algoSortThread, m_algoSortThread, h_algoSortThread;
    private AlgoCheckThread i_algoCheckThread, b_algoCheckThread, q_algoCheckThread, s_algoCheckThread, m_algoCheckThread, h_algoCheckThread;
    private ShuffleThread shuffleThread;
    private StopWatch m_timer;
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel bAvTimeLabel;
    private javax.swing.JLabel bAverageSortTimeLabel;
    private javax.swing.JLabel bListLabel;
    private javax.swing.JLabel bSortTimeLabel;
    private javax.swing.JLabel bStatusLabel;
    private javax.swing.JLabel bTimeLabel;
    private javax.swing.JPanel bubbleSortPanel;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JRadioButton characterRadioButton;
    private javax.swing.JLabel finalTimesLabel;
    private javax.swing.JLabel hAvTimeLabel;
    private javax.swing.JLabel hAverageSortTimeLabel;
    private javax.swing.JLabel hListLabel;
    private javax.swing.JLabel hSortTimeLabel;
    private javax.swing.JLabel hStatusLabel;
    private javax.swing.JLabel hTimeLabel;
    private javax.swing.JPanel heapSortPanel;
    private javax.swing.JLabel iAvTimeLabel;
    private javax.swing.JLabel iAverageSortTimeLabel;
    private javax.swing.JLabel iListLabel;
    private javax.swing.JLabel iSortTimeLabel;
    private javax.swing.JLabel iStatusLabel;
    private javax.swing.JLabel iTimeLabel;
    private javax.swing.JPanel insertionSortPanel;
    private javax.swing.JRadioButton integerRadioButton;
    private javax.swing.JComboBox itemsComboBox;
    private javax.swing.JLabel itemsLabel;
    private javax.swing.JLabel mAvTimeLabel;
    private javax.swing.JLabel mAverageSortTimeLabel;
    private javax.swing.JLabel mListLabel;
    private javax.swing.JLabel mSortTimeLabel;
    private javax.swing.JLabel mStatusLabel;
    private javax.swing.JLabel mTimeLabel;
    private javax.swing.JPanel mergeSortPanel;
    private javax.swing.JComboBox nIntComboBox;
    private javax.swing.JLabel nIntLabel;
    private javax.swing.JLabel qAvTimeLabel;
    private javax.swing.JLabel qAverageSortTimeLabel;
    private javax.swing.JLabel qListLabel;
    private javax.swing.JLabel qSortTimeLabel;
    private javax.swing.JLabel qStatusLabel;
    private javax.swing.JLabel qTimeLabel;
    private javax.swing.JPanel quickSortPanel;
    private javax.swing.JButton resetButton;
    private javax.swing.JLabel sAvTimeLabel;
    private javax.swing.JLabel sAverageSortTimeLabel;
    private javax.swing.JLabel sListLabel;
    private javax.swing.JLabel sSortTimeLabel;
    private javax.swing.JLabel sStatusLabel;
    private javax.swing.JLabel sTimeLabel;
    private javax.swing.JPanel selectionSortPanel;
    private javax.swing.JButton startButton;
    // End of variables declaration//GEN-END:variables
}
